#include "shareManager.h"

SerialSlave::SerialSlave(QObject *parent) :
    QObject(parent)
{
    //    qDebug()<<"mianThreadID:"<<QThread::currentThreadId();
}

SerialSlave::~SerialSlave()
{
    qDebug()<<"串口线程析构";
    //有问题
//    closeSerialPort();
}

bool SerialSlave::openSerialPort(QString port)
{
    serialPort = new Win_QextSerialPort(port, QextSerialBase::Polling);

    if(!serialPort->open(QIODevice::ReadWrite))
    {
        delete serialPort;
        return false;
    }
    serialPort->setBaudRate(BAUD115200);
    serialPort->setDataBits(DATA_8);
    serialPort->setStopBits(STOP_1);
    serialPort->setParity(PAR_NONE);
    serialPort->setFlowControl(FLOW_OFF);
    serialPort->setTimeout(2);

    //QextSerialBase::EventDriven方式信号槽
//    connect(serialPort, SIGNAL(readyRead()), this, SLOT(slot_readSerialData()));

    connect(&timer_polling, SIGNAL(timeout()), this, SLOT(slot_readSerialData()));
    timer_polling.start(5);//*这个应该移动到workThread.start();之后,否则定时器触发了，线程却没跑

    moveToThread(&workThread);
    workThread.start();

//    sharePointer->handleThread.startThread();

    return true;
}

void SerialSlave::closeSerialPort()
{
    if(serialPort->isOpen())
    {
        //1.先关定时器
        timer_polling.stop();
        //2.然后关串口
        serialPort->close();
        //3.再停止线程
        workThread.terminate();
        //4.释放空间
        delete serialPort;
    }
}

void SerialSlave::sendCalibrationCMD()
{
    char cmd[] = {0xA5, 0x5A, 0xA1};

    serialPort->write(QByteArray::fromRawData(cmd, sizeof(cmd)));
}

//5ms timer
void SerialSlave::slot_readSerialData()
{
    if(serialPort->bytesAvailable() > 0)
    {
        //加入缓冲区
        sharePointer->rxBuffer.append(serialPort->readAll());

//        qDebug()<<sharePointer->rxBuffer.size();

        serialBufferHandle(sharePointer->rxBuffer);
    }
}

void SerialSlave::serialBufferHandle(QByteArray &buf)
{
    //防止buffer爆炸，放在前面防止缓冲中冗余数据让下面的 while()做无用功
    if(buf.size() > 512)
    {buf.clear();}

    //没找到帧结束符
    if(!buf.contains('\n'))
    {return;}

    int nFramePos = 0;
    //改：只要含有‘\n’，就解析完，防止漏帧
    while(buf.contains('\n'))
    {
        //讲一帧数据取出并从缓冲区移除
        nFramePos = buf.indexOf('\n');
        QByteArray tmpBuf = buf.mid(0, nFramePos + 1);// +1 -> \n
        buf.remove(0, nFramePos + 1);

        //1.判断帧头
        if(tmpBuf[0] != (char)0x55 || tmpBuf[1] != (char)0x55)
        {return;}//错误帧

        //2.校验长度
        if((quint8)tmpBuf[3] != (tmpBuf.size()-5))
        {return;}//实际长度 != 接收长度

        //3.提取功能字
        char funcWord = tmpBuf[2];

        //4.根据功能字解码
        switch(funcWord)
        {
        case (char)0xA2 :
            AHRSHandle(tmpBuf);
            break;

        case (char)0xA3 :
            RCHandle(tmpBuf);
            break;

        case (char)0xA4 :
            GPSHandle(tmpBuf);
            break;

        case (char)0xA5 :
            MOTORHandle(tmpBuf);
            break;

        default : break;
        }
    }
}

void SerialSlave::RCHandle(const QByteArray &buf)
{
    sharePointer->lockRC.lock();

    char *p = (char*)(&(sharePointer->RC_Values.CH1));
    for(int i = 4; i < buf.size()-1; i++)
    {
      *p++ = (char)buf[i];
    }

    sharePointer->lockRC.unlock();
}

void SerialSlave::AHRSHandle(const QByteArray &buf)
{
    sharePointer->lockAHRS.lock();

    char *p = (char *)&sharePointer->AHRS_values.YAW;
    for(int i = 4; i < buf.size()-1; i++)
    {
      *p++ = (char)buf[i];
    }

    sharePointer->lockAHRS.unlock();
}

void SerialSlave::GPSHandle(const QByteArray &buf)
{
    sharePointer->lockGPS.lock();

    char *p = (char *)&sharePointer->GPS_values.longtitude;
    for(int i = 4; i < buf.size()-1; i++)
    {
      *p++ = (char)buf[i];
    }

    sharePointer->lockGPS.unlock();
}

void SerialSlave::MOTORHandle(const QByteArray &buf)
{
    sharePointer->lockMOTOR.lock();

    char *p = (char *)&sharePointer->MOTOR_values.motor1;
    for(int i = 4; i < buf.size()-1; i++)
    {
      *p++ = (char)buf[i];
    }

    sharePointer->lockMOTOR.unlock();
}

